import json
import pickle
import base64
from django.http import JsonResponse
from django.shortcuts import render

# Create your views here.
from django.views import View
from django_redis import get_redis_connection
from apps.goods.models import SKU


class CartsView(View):

    def get(self, request):
        user = request.user
        carts = {}
        if user.is_authenticated:
            redis_cli = get_redis_connection('carts')
            redis_carts = redis_cli.hgetall('carts_%s' % user.id)
            redis_selected = redis_cli.smembers('selected_%s' % user.id)
            for sku_id, count in redis_carts.items():
                carts[int(sku_id)] = {
                    "count": int(count),
                    'selected': sku_id in redis_selected,
                }
        else:
            carts = request.COOKIES.get('carts')
            if carts:
                carts = pickle.loads(base64.b64decode(carts.encode()))
        sku_ids = carts.keys()
        skus = SKU.objects.filter(id__in=sku_ids)
        cart_skus = [{
            'id': sku.id,
            'name': sku.name,
            'price': sku.price,
            'count': carts.get(sku.id)['count'],
            'selected': carts.get(sku.id)['selected'],
            'default_image_url': sku.default_image.url,
            'amount': sku.price * carts.get(sku.id)['count'],
        } for sku in skus]

        return JsonResponse({'code': 0, 'errmsg': 'ok', 'cart_skus': cart_skus})

    def post(self, request):
        # 1、获取前端数据
        data_dict = json.loads(request.body.decode())
        sku_id = data_dict.get('sku_id')
        count = data_dict.get('count')
        # 2、校验数据
        if not all([sku_id, count]):
            return JsonResponse({'code': 400, 'errmsg': '缺少参数'})
        try:
            sku = SKU.objects.get(id=sku_id)
        except Exception as e:
            return JsonResponse({'code': 400, 'errmsg': '无此商品'})
        try:
            count = int(count)
        except Exception as e:
            return JsonResponse({'code': 400, 'errmsg': '参数count有误'})
        user = request.user
        # 3、保存数据
        #  3.1、登录状态   redis保存
        if user.is_authenticated:
            redis_cli = get_redis_connection('carts')
            redis_pipeline = redis_cli.pipeline()
            redis_pipeline.hincrby('carts_%s' % user.id, sku_id, count)
            redis_pipeline.sadd('selected_%s' % user.id, sku_id)
            redis_pipeline.execute()
            return JsonResponse({'code': 0, 'errmsg': '添加购物车成功'})
        #  3.2、未登录状态    cookies保存
        else:
            carts = request.COOKIES.get('carts')
            # 是否已保存
            if carts:
                carts = pickle.loads(base64.b64decode(carts.encode()))
            else:
                carts = {}
            if sku_id in carts.keys():
                pre_count = carts.get(sku_id)['count']
                count += pre_count
            carts[sku_id] = {
                'count': count,
                'selected': True
            }
            carts_bytes = pickle.dumps(carts)
            carts_b64 = base64.b64encode(carts_bytes)
            response = JsonResponse({'code': 0, 'errmsg': 'ok'})
            response.set_cookie('carts', carts_b64.decode(), max_age=3600*24*7)
            return response
        # 4、返回响应

    def put(self, request):
        data_dict = json.loads(request.body.decode())
        sku_id = data_dict.get('sku_id')
        count = data_dict.get('count')
        selected = data_dict.get('selected', True)
        if not all([sku_id, count]):
            return JsonResponse({'code': 400, 'errmsg': '缺少参数'})
        try:
            sku = SKU.objects.get(id=sku_id)
        except Exception as e:
            return JsonResponse({'code': 400, 'errmsg': '无此商品'})
        try:
            count = int(count)
        except Exception as e:
            return JsonResponse({'code': 400, 'errmsg': '参数count有误'})
        user = request.user
        if user.is_authenticated:
            redis_cli = get_redis_connection('carts')
            redis_pipeline = redis_cli.pipeline()
            redis_pipeline.hset('carts_%s' % user.id, sku_id, count)
            if selected:
                redis_pipeline.sadd('selected_%s' % user.id, sku_id)
            else:
                redis_pipeline.srem('selected_%s' % user.id, sku_id)
            redis_pipeline.execute()
            cart_sku = {
                'id': sku_id,
                'count': count,
                'selected': selected,
                'name': sku.name,
                'default_image_url': sku.default_image.url,
                'price': sku.price,
                'amount': sku.price * count,
            }
            return JsonResponse({'code': 0, 'errmsg': '修改购物车成功', 'cart_sku': cart_sku})
        else:
            carts = request.COOKIES.get('carts')
            if carts:
                carts = pickle.loads(base64.b64decode(carts.encode()))
            else:
                carts = {}
            carts[sku_id] = {
                'count': count,
                'selected': selected
            }
            cart_sku = {
                'id': sku_id,
                'count': count,
                'selected': selected,
                'name': sku.name,
                'default_image_url': sku.default_image.url,
                'price': sku.price,
                'amount': sku.price * count,
            }
            carts_bytes = pickle.dumps(carts)
            carts_b64 = base64.b64encode(carts_bytes)
            response = JsonResponse({'code': 0, 'errmsg': '修改购物车成功', 'cart_sku': cart_sku})
            response.set_cookie('carts', carts_b64.decode(), max_age=3600 * 24 * 7)
            return response

    def delete(self, request):
        data_dict = json.loads(request.body.decode())
        sku_id = data_dict.get('sku_id')
        try:
            sku = SKU.objects.get(id=sku_id)
        except Exception as e:
            return JsonResponse({'code': 400, 'errmsg': '无此商品'})
        user = request.user
        if user.is_authenticated:
            redis_cli = get_redis_connection('carts')
            redis_pipeline = redis_cli.pipeline()
            redis_pipeline.hdel('carts_%s' % user.id, sku_id)
            redis_pipeline.srem('selected_%s' % user.id, sku_id)
            redis_pipeline.execute()
            return JsonResponse({'code': 0, 'errmsg': '删除购物车成功'})
        else:
            carts = request.COOKIES.get('carts')
            carts = pickle.loads(base64.b64decode(carts.encode()))
            if sku_id in carts.keys():
                del carts[sku_id]
            carts_bytes = pickle.dumps(carts)
            carts_b64 = base64.b64encode(carts_bytes)
            response = JsonResponse({'code': 0, 'errmsg': '删除购物车成功'})
            response.set_cookie('carts', carts_b64.decode(), max_age=3600 * 24 * 7)
            return response


class CartsSelectAllView(View):
    def put(self, request):
        data_dict = json.loads(request.body.decode())
        selected = data_dict.get('selected', True)
        # 校验参数
        if selected:
            if not isinstance(selected, bool):
                return JsonResponse({'code': 400, 'errmsg': '参数selected有误'})
        user = request.user
        if user.is_authenticated:
            redis_cli = get_redis_connection('carts')
            redis_carts = redis_cli.hgetall('carts_%s' % user.id)
            if selected:
                redis_cli.sadd('selected_%s' % user.id, *list(redis_carts.keys()))
            else:
                redis_cli.srem('selected_%s' % user.id, *list(redis_carts.keys()))
            return JsonResponse({'code': 0, 'errmsg': 'ok'})
        else:
            carts = request.COOKIES.get('carts')
            response = JsonResponse({'code': 0, 'errmsg': 'ok'})
            if carts:
                carts = pickle.loads(base64.b64decode(carts.encode()))
                for sku_id in carts:
                    carts[sku_id]['selected'] = selected
                carts_bytes = pickle.dumps(carts)
                carts_b64 = base64.b64encode(carts_bytes)
                response.set_cookie('carts', carts_b64.decode(), max_age=3600 * 24 * 7)
            return response


class CartsSimpleView(View):
    def get(self, request):
        user = request.user
        carts = {}
        if user.is_authenticated:
            redis_cli = get_redis_connection('carts')
            redis_carts = redis_cli.hgetall('carts_%s' % user.id)
            for sku_id, count in redis_carts.items():
                carts[int(sku_id)] = {
                    'count': int(count)
                }
        else:
            carts = request.COOKIES.get('carts')
            if carts:
                carts = pickle.loads(base64.b64decode(carts.encode()))
        skus = SKU.objects.filter(id__in=carts.keys())
        cart_skus = [{
            'id': sku.id,
            'name': sku.name,
            'count': carts.get(sku.id)['count'],
            'default_image_url': sku.default_image.url,
        } for sku in skus]
        return JsonResponse({'code': 0, 'errmsg': 'ok', 'cart_skus': cart_skus})
